home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1990 Riet Oolman
-
- This file is part of GLASS.
-
- GLASS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- GLASS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GLASS; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* file: unification.c
- author: H. Oolman
- last changed: 13-7-'90
- purpose: unification of types for type-checking of GLASS
- modifications:
- updated for new version of Glass
- p2c translated, tmc access procs
- */
-
- #include "handleds.h"
- #include "check.ds.h"
- #include "check.var.h"
- #include "check.afuncs.h"
- #include "errorenv.h"
- #include "unification.h"
-
- /* unification procedures for types. The types can have < relations */
-
- Void becomes(t1, t2)
- typcrec *t1, *t2;
- {
- /* t1 (tag UNKNOWN or SOME) should be changed to t2. This is done by
- indirection. Therefore care must be taken to let all occurrences of t1 with
- the same number have the same record. On inspecting
- a type, these INDIRs should always be skipped */
- t1->kind = kindINDIR;
- t1->INDIR.tcind = t2;
- }
-
-
- boolean occurs(n, t)
- long n;
- typcrec *t;
- {
- /* see if typename n does not occur as a real subpart of type t (this is not
- allowed) */
-
- while (t->kind == kindINDIR) t = t->INDIR.tcind;
- switch (t->kind) {
-
- case kindUNKNOWN:
- return (t->UNKNOWN.unknm == n);
- break;
-
- case kindSOME:
- if (t->SOME.somnr == n)
- return true;
- else
- return occurs(n, t->SOME.tcpart);
- break;
-
- case kindSINGLEARROW:
- return occurs(n, t->SINGLEARROW.tcarg) | occurs(n, t->SINGLEARROW.tcres);
- break;
-
- case kindCT:
- return occurs(n, t->CT.tcfirst) | occurs(n, t->CT.tcrest);
- break;
-
- case kindSYSTY:
- return occurs(n, t->SYSTY.syscomp);
- break;
-
- case kindINT:
- case kindFLOAT:
- case kindBOOL:
- case kindSTRING:
- case kindEMPTYT:
- case kindBASETY:
- case kindAPS:
- case kindLOC:
- return false;
- break;
-
- case kindALL:
- return occurs(n, t->ALL.tcall);
- break;
- }
- } /* occurs */
-
-
- boolean restrictable(mustendemp, mustconn, ty, vl)
- boolean mustendemp, mustconn;
- typcrec *ty;
- val vl;
- {
- /* if mustendemp then ty must be a (tuple) type ending in the empty
- type; if mustconn ty may only be a type fit for connections. Error
- if conditions not fullfilled.
- UNKNOWNs in ty are restricted (in their mustendemp and mustconn fields)
- to the demands
- The result tells if restricting could be done without errors
- vl: the expression that causes restrictable to be called */
- boolean rb;
-
- rb = true;
- if (!(mustendemp || mustconn)) return rb;
- while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
- switch (ty->kind) {
-
- case kindSYSTY:
- case kindINT:
- case kindFLOAT:
- case kindBOOL:
- case kindSTRING:
- case kindAPS:
- case kindSINGLEARROW:
- if (mustendemp) {
- error(15L, ty, NULL, NULL, vl, false);
- rb = false;
- }
- if (mustconn) {
- rb = false;
- error(16L, ty, NULL, NULL, vl, false);
- }
- break;
-
- case kindEMPTYT: /* always right */
- break;
-
- case kindLOC:
- if (mustendemp) {
- rb = false;
- error(15L, ty, NULL, NULL, vl, false);
- }
- break;
-
- case kindCT:
- rb = restrictable(false, mustconn, ty->CT.tcfirst, vl) |
- restrictable(false, mustconn, ty->CT.tcrest, vl);
- break;
-
- /* assumption: CT only constructed with mustendemp satisfied */
- case kindALL:
- rb = false;
- error(10L, NULL, NULL, Buildsymbol("restrictable", 12L), NULL, false);
- break;
-
- case kindUNKNOWN:
- ty->UNKNOWN.mustendemp = (ty->UNKNOWN.mustendemp || mustendemp);
- ty->UNKNOWN.mustconn = (ty->UNKNOWN.mustconn || mustconn);
- break;
-
- case kindSOME:
- rb = restrictable(false, mustconn, ty->SOME.tcpart, vl);
- break;
-
- case kindBASETY:
- if (mustendemp) {
- rb = false;
- error(15L, ty, NULL, NULL, vl, false);
- }
- break;
- }
- return rb;
- } /* restrictable */
-
-
- Local Void largerdir(dg1, dg2, direrfnd, vl)
- dirgraphrec *dg1, *dg2;
- boolean *direrfnd;
- val vl;
- {
- /* dg1 should be larger than dg2. dgi are directions of a system's type.
- ? < none, ! < none
- direrfnd<-> direction error already found and notified
- vl: for which an error can be found */
- switch (dg1->kind) {
-
- case kindCd:
- switch (dg2->kind) {
-
- case kindCd:
- largerdir(dg1->Cd.dgfirst, dg2->Cd.dgfirst, direrfnd, vl);
- largerdir(dg1->Cd.dgrest, dg2->Cd.dgrest, direrfnd, vl);
- break;
-
- case kindSd:
- largerdir(dg1->Cd.dgfirst, dg2->Sd.dgpart, direrfnd, vl);
- largerdir(dg1->Cd.dgrest, dg2, direrfnd, vl);
- break;
-
- case kindOd:
- largerdir(dg1->Cd.dgfirst, dg2, direrfnd, vl);
- largerdir(dg1->Cd.dgrest, dg2, direrfnd, vl);
- break;
- }
- break;
-
- case kindSd:
- switch (dg2->kind) {
-
- case kindCd:
- largerdir(dg1->Sd.dgpart, dg2->Cd.dgfirst, direrfnd, vl);
- largerdir(dg1, dg2->Cd.dgrest, direrfnd, vl);
- break;
-
- case kindSd:
- largerdir(dg1->Sd.dgpart, dg2->Sd.dgpart, direrfnd, vl);
- largerdir(dg1->Sd.dglast, dg2->Sd.dglast, direrfnd, vl);
- break;
-
- case kindOd:
- largerdir(dg1->Sd.dgpart, dg2, direrfnd, vl);
- largerdir(dg1->Sd.dglast, dg2, direrfnd, vl);
- break;
- }
- break;
-
- case kindOd:
- switch (dg2->kind) {
-
- case kindCd:
- largerdir(dg1, dg2->Cd.dgfirst, direrfnd, vl);
- largerdir(dg1, dg2->Cd.dgrest, direrfnd, vl);
- break;
-
- case kindSd:
- largerdir(dg1, dg2->Sd.dgpart, direrfnd, vl);
- largerdir(dg1, dg2->Sd.dglast, direrfnd, vl);
- break;
-
- case kindOd:
- if (!*direrfnd && dg1->Od.basedir->kind != dg2->Od.basedir->kind &&
- dg1->Od.basedir->kind != kindNON) {
- error(14L, NULL, NULL, NULL, vl, false);
- *direrfnd = true;
- }
- break;
- }
- break;
- }
- } /* largerdir */
-
-
- Void compat(t1, t2, vl)
- typcrec *t1, *t2;
- val vl;
- {
- /* change unknown parts of t1 and t2 (as little as possible) (by becomes)
- such that t2 after that can be enlarged to t1 (t2<t1)
- vl: expression that causes the compat to be done */
- typcrec *ht;
- boolean direrfnd;
-
- /* !! bij invullen van namen moet < / > gebruikt */
- while (t2->kind == kindINDIR) t2 = t2->INDIR.tcind;
- while (t1->kind == kindINDIR) t1 = t1->INDIR.tcind;
- if (t2->kind == kindUNKNOWN) {
- if (t1->kind == kindUNKNOWN)
- { if (t2->UNKNOWN.unknm != t1->UNKNOWN.unknm)
- { if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return;
- }
- if (occurs(t2->UNKNOWN.unknm, t1))
- error(11L, t1, NULL, NULL, NULL, false);
- else {
- if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return;
- }
- switch (t1->kind) {
-
- case kindUNKNOWN:
- if (occurs(t1->UNKNOWN.unknm, t2))
- error(11L, t2, NULL, NULL, NULL, false);
- else {
- if (restrictable(t1->UNKNOWN.mustendemp, t1->UNKNOWN.mustconn, t2, vl))
- becomes(t1, t2);
- }
- break;
-
- case kindSINGLEARROW:
- if (t2->kind == kindSINGLEARROW) {
- compat(t2->SINGLEARROW.tcarg, t1->SINGLEARROW.tcarg, vl);
- compat(t1->SINGLEARROW.tcres, t2->SINGLEARROW.tcres, vl);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindINT:
- if (t2->kind != kindINT)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindFLOAT:
- if (t2->kind != kindFLOAT)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindBOOL:
- if (t2->kind != kindBOOL)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindSTRING:
- if (t2->kind != kindSTRING)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindSYSTY:
- if (t2->kind == kindSYSTY) {
- direrfnd = false;
- largerdir(t1->SYSTY.sysdirs, t2->SYSTY.sysdirs, &direrfnd, vl);
- compat(t1->SYSTY.syscomp, t2->SYSTY.syscomp, vl);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindAPS:
- /* if t2^.kind = kindSYSTY
- then compat(BuildSYSTY(BuildOd(BuildNON),BuildBUNDLE(ht)),t2,vl)
- else */
- if (t2->kind != kindAPS)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindCT:
- if (t2->kind == kindCT) {
- compat(t1->CT.tcfirst, t2->CT.tcfirst, vl);
- compat(t1->CT.tcrest, t2->CT.tcrest, vl);
- } else if (t2->kind == kindSOME) {
- if (!occurs(t2->SOME.somnr, t1)) {
- ht = BuildCT(t2->SOME.tcpart, BuildSOME(t2->SOME.tcpart, newname()));
- becomes(t2, ht);
- compat(t1, ht, vl);
- } else
- error(11L, t1, NULL, NULL, NULL, false);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindLOC:
- if (t2->kind == kindLOC) {
- if (!(Equalsymbol(t2->LOC.locname, t1->LOC.locname) &&
- t1->LOC.inst == t2->LOC.inst))
- error(12L, t2, t1, NULL, vl, false);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindBASETY:
- if (t2->kind == kindBASETY) {
- if (!(Equalsymbol(t2->BASETY.btname, t1->BASETY.btname) &&
- t1->BASETY.bnr == t2->BASETY.bnr))
- error(12L, t2, t1, NULL, vl, false);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindSOME:
- if (t2->kind == kindCT) {
- if (!occurs(t1->SOME.somnr, t2)) {
- ht = BuildCT(t1->SOME.tcpart, BuildSOME(t1->SOME.tcpart, newname()));
- becomes(t1, ht);
- compat(ht, t2, vl);
- } else
- error(11L, t2, NULL, NULL, NULL, false);
- } else if (t2->kind == kindSOME) {
- compat(t1->SOME.tcpart, t2->SOME.tcpart, vl);
- if (t1->SOME.somnr != t2->SOME.somnr) {
- if (!occurs(t1->SOME.somnr, t2)) {becomes(t1, t2);}
- else error(11L, t1, NULL, NULL, NULL, false);
- }
- } else if (t2->kind == kindEMPTYT) {
- if (!forfull)
- becomes(t1, t2);
- } else
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindEMPTYT:
- if (!forfull && t2->kind == kindSOME)
- becomes(t2, t1);
- else if (t2->kind != kindEMPTYT)
- error(12L, t2, t1, NULL, vl, false);
- break;
-
- case kindALL:
- /* ALL should not be treated here */
- error(10L, NULL, NULL, Buildsymbol(
- "compat ",
- 6L), NULL, false);
- break;
- }
- } /* compat */
-
-
- Static dirgraphrec *uplodir(islower_, dg1, dg2, direrfnd, vl)
- boolean islower_;
- dirgraphrec *dg1, *dg2;
- boolean *direrfnd;
- val vl;
- {
- /* delivers the largest lowerbound of dg1 and dg2 if islower is true,
- delivers the smallest upperbound of dg1 and dg2 if islower is false
- direrfnd: direction error already found and notified
- vl: for which an error can be found */
- dirgraphrec *Result;
-
- switch (dg1->kind) {
-
- case kindCd:
- switch (dg2->kind) {
-
- case kindCd:
- Result = BuildCd(uplodir(islower_, dg1->Cd.dgfirst,
- dg2->Cd.dgfirst, direrfnd, vl),
- uplodir(islower_, dg1->Cd.dgrest,
- dg2->Cd.dgrest, direrfnd, vl));
- break;
-
- case kindSd:
- Result = BuildCd(uplodir(islower_, dg1->Cd.dgfirst,
- dg2->Sd.dgpart, direrfnd, vl),
- uplodir(islower_, dg1->Cd.dgrest, dg2, direrfnd, vl));
- break;
-
- case kindOd:
- Result = BuildCd(uplodir(islower_, dg1->Cd.dgfirst, dg2, direrfnd,
- vl), uplodir(islower_, dg1->Cd.dgrest,
- dg2, direrfnd, vl));
- break;
- }
- break;
-
- case kindSd:
- switch (dg2->kind) {
-
- case kindCd:
- Result = BuildCd(uplodir(islower_, dg1->Sd.dgpart,
- dg2->Cd.dgfirst, direrfnd, vl),
- uplodir(islower_, dg1, dg2->Cd.dgrest, direrfnd, vl));
- break;
-
- case kindSd:
- Result = BuildSd(uplodir(islower_, dg1->Sd.dgpart,
- dg2->Sd.dgpart, direrfnd, vl),
- uplodir(islower_, dg1->Sd.dglast,
- dg2->Sd.dglast, direrfnd, vl));
- break;
-
- case kindOd:
- Result = BuildSd(uplodir(islower_, dg1->Sd.dgpart, dg2, direrfnd,
- vl), uplodir(islower_, dg1->Sd.dglast,
- dg2, direrfnd, vl));
- break;
- }
- break;
-
- case kindOd:
- switch (dg2->kind) {
-
- case kindCd:
- Result = BuildCd(uplodir(islower_, dg1, dg2->Cd.dgfirst, direrfnd,
- vl),
- uplodir(islower_, dg1, dg2->Cd.dgrest, direrfnd, vl));
- break;
-
- case kindSd:
- Result = BuildSd(uplodir(islower_, dg1, dg2->Sd.dgpart, direrfnd,
- vl),
- uplodir(islower_, dg1, dg2->Sd.dglast, direrfnd, vl));
- break;
-
- case kindOd:
- if (islower_) {
- if (dg1->Od.basedir->kind == dg2->Od.basedir->kind ||
- dg2->Od.basedir->kind == kindNON)
- Result = dg1;
- else {
- if (dg1->Od.basedir->kind == kindNON)
- Result = dg2;
- else {
- if (!*direrfnd)
- error(13L, NULL, NULL, NULL, vl, false);
- *direrfnd = true;
- Result = BuildOd(BuildNON());
- }
- }
- } else if (dg1->Od.basedir->kind == dg2->Od.basedir->kind)
- Result = dg1;
- else
- Result = BuildOd(BuildNON());
- break;
- }
- break;
- }
- return Result;
- } /* uplodir */
-
-
- /* changes t1 and t2 (as little as needed) such that lower<ti
- (largest lowerbound)
- vl: the expression that causes this function to be called */
- Static typcrec *lower PP((typcrec *t1, typcrec *t2, val vl));
-
-
- typcrec *upper(t1, t2, vl)
- typcrec *t1, *t2;
- val vl;
- {
- /* changes t1 and t2 (as little as needed) such that upper>ti
- (smallest upperbound)
- vl: the expression that causes this procedure to be called */
- typcrec *ht;
- dirgraphrec *di;
- boolean direrfnd;
-
- /* !! invulling niet gedetailleerd genoeg */
- while (t2->kind == kindINDIR) t2 = t2->INDIR.tcind;
- while (t1->kind == kindINDIR) t1 = t1->INDIR.tcind;
- if (t2->kind == kindUNKNOWN)
- { if (t1->kind == kindUNKNOWN)
- { if (t2->UNKNOWN.unknm != t1->UNKNOWN.unknm)
- { if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return t2;
- }
- if (occurs(t2->UNKNOWN.unknm, t1))
- {error(11L, t1, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- else
- { if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return t2;
- }
- switch (t1->kind) {
-
- case kindUNKNOWN:
- if (occurs(t1->UNKNOWN.unknm, t2))
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- else
- { if (restrictable(t1->UNKNOWN.mustendemp, t1->UNKNOWN.mustconn, t2, vl))
- becomes(t1, t2);
- }
- break;
-
- case kindSINGLEARROW:
- if (t2->kind == kindSINGLEARROW)
- return BuildSINGLEARROW(lower(t2->SINGLEARROW.tcarg, t1->SINGLEARROW.tcarg, vl),
- upper(t1->SINGLEARROW.tcres, t2->SINGLEARROW.tcres, vl));
- else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindINT:
- if (t2->kind != kindINT)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindFLOAT:
- if (t2->kind != kindFLOAT)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindBOOL:
- if (t2->kind != kindBOOL)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSTRING:
- if (t2->kind != kindSTRING)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSYSTY:
- if (t2->kind == kindSYSTY) {
- direrfnd = false;
- di = uplodir(false, t1->SYSTY.sysdirs, t2->SYSTY.sysdirs, &direrfnd,
- vl);
- ht = upper(t1->SYSTY.syscomp, t2->SYSTY.syscomp, vl);
- if (direrfnd)
- ht = BuildUNKNOWN(newname(), false, true);
- return BuildSYSTY(di, ht);
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- /*
- else
- if t2^.kind=APS
- then
- begin
- compat(BuildSYSTY(BuildOd(BuildNON),BuildBUNDLE(ht)), t1,vl);
- upper:=t2
- end
- else if t2^.kind=BUNDLE
- then
- begin
- compat(BuildSYSTY(BuildCd(BuildOd(BuildIN),BuildOd(BuildOUT))
- ,
- BuildBUNDLE(BuildCT(ht, t2^.typc4))
- )
- , t1
- , vl);
- upper:=t2
- end
- else if t2^.kind = EMPTYT
- then
- begin
- compat(BuildSYSTY(BuildCd(BuildOd(BuildIN),BuildOd(BuildOUT))
- , BuildBUNDLE(BuildCT(ht, t2))
- )
- , t1
- , vl);
- upper:=BuildBUNDLE(t2)
- end
- */
- break;
-
- case kindAPS:
- /* if t2^.kind = kindSYSTY
- then compat(BuildSYSTY(BuildOd(BuildNON),BuildBUNDLE(ht)),t2,vl)
- else */
- if (t2->kind != kindAPS)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindCT:
- if (t2->kind == kindCT)
- return BuildCT(upper(t1->CT.tcfirst, t2->CT.tcfirst, vl),
- upper(t1->CT.tcrest, t2->CT.tcrest, vl));
- else if (t2->kind == kindSOME) {
- if (!occurs(t2->SOME.somnr, t1)) {
- ht = BuildCT(t2->SOME.tcpart, BuildSOME(t2->SOME.tcpart, newname()));
- becomes(t2, ht);
- return upper(t1, ht, vl);
- } else
- {error(11L, t1, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindLOC:
- if (t2->kind == kindLOC) {
- if (!(Equalsymbol(t2->LOC.locname, t1->LOC.locname) &&
- t1->LOC.inst == t2->LOC.inst))
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindBASETY:
- if (t2->kind == kindBASETY) {
- if (!(Equalsymbol(t1->BASETY.btname, t2->BASETY.btname) &&
- t1->BASETY.bnr == t2->BASETY.bnr))
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSOME:
- if (t2->kind == kindCT)
- { if (!occurs(t1->SOME.somnr, t2))
- { ht = BuildCT(t1->SOME.tcpart, BuildSOME(t1->SOME.tcpart, newname()));
- becomes(t1, ht);
- return upper(ht, t2, vl);
- } else
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else if (t2->kind == kindSOME)
- {ht = BuildSOME(upper(t1->SOME.tcpart, t2->SOME.tcpart, vl),
- t2->SOME.somnr);
- if (t1->SOME.somnr != t2->SOME.somnr)
- { if (!occurs(t1->SOME.somnr, t2))
- {becomes(t1, t2);} /* !! moet dit wel? */
- else
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- }
- return ht;
- } else if (t2->kind == kindEMPTYT) {
- if (!forfull) becomes(t1, t2);
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindEMPTYT:
- if (t2->kind == kindSOME) {
- if (!forfull) becomes(t2, t1);
- } else {
- if (t2->kind != kindEMPTYT)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- }
- /*
- else
- if t2^.kind=LIST
- then upper:=t2
- else
- if t2^.kind=BUNDLE
- then upper:=BuildBUNDLE(upper(ht,t2^.typc4,vl))
- else
- if t2^.kind = SYSTY
- then
- begin
- if forfull
- then ht2:=BuildSOME(BuildUNKNOWN(newname),newname)
- else ht2:=BuildEMPTYT;
- compat(BuildSYSTY(BuildCd(BuildOd(BuildIN),BuildOd(BuildOUT))
- , BuildBUNDLE(BuildCT(ht, ht2))
- )
- , t2
- , vl);
- upper:=BuildBUNDLE(t1)
- end
- */
- break;
-
- case kindALL:
- {error(10L, NULL, NULL, Buildsymbol( "upper", 5L), NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
- /* ALL should not be treated here */
- }
- return t1;
- } /* upper */
-
-
- typcrec *uppercomps(ty, vl)
- typcrec *ty;
- val vl;
- {
- /* ty must be composed of a number of the same parts; the result
- is the smallest type larger than each part
- vl: the expression that causes this to be called */
- typcrec *un;
- errorrec *erl;
- typcrec *tp;
-
- while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
- if (ty->kind == kindUNKNOWN)
- { un = BuildUNKNOWN(newname(), false, ty->UNKNOWN.mustconn);
- /* !! hier ook gevaar verkeerde invulling? */
- becomes(ty, BuildSOME(un, newname()));
- return un;
- } else {
- if (ty->kind == kindSOME) return (ty->SOME.tcpart);
- else {
- if (ty->kind == kindCT)
- { erl=errorlist;
- tp = upper(ty->CT.tcfirst, uppercomps(ty->CT.tcrest, vl),
- vl);
- if (errorlist==erl) return tp;
- else
- { error(17L, NULL, NULL, NULL, vl, false);
- return tp;
- }
- }
- else {
- if (ty->kind != kindEMPTYT)
- error(17L, NULL, NULL, NULL, vl, false);
- return (BuildUNKNOWN(newname(), false, false));
- }
- }
- }
- } /* uppercomps */
-
-
- Static typcrec *lower(t1, t2, vl)
- typcrec *t1, *t2;
- val vl;
- {
- typcrec *ht;
- dirgraphrec *di;
- boolean direrfnd;
-
- /* !! invulling niet gedetaillerd genoeg */
- while (t2->kind == kindINDIR) t2 = t2->INDIR.tcind;
- while (t1->kind == kindINDIR) t1 = t1->INDIR.tcind;
- if (t2->kind == kindUNKNOWN) {
- if (t1->kind == kindUNKNOWN) {
- if (t2->UNKNOWN.unknm != t1->UNKNOWN.unknm) {
- if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return t2;
- }
- if (occurs(t2->UNKNOWN.unknm, t1))
- {error(11L, t1, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- else {
- if (restrictable(t2->UNKNOWN.mustendemp, t2->UNKNOWN.mustconn, t1, vl))
- becomes(t2, t1);
- }
- return t2;
- }
- switch (t1->kind) {
-
- case kindUNKNOWN:
- if (occurs(t1->UNKNOWN.unknm, t2))
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- else {
- if (restrictable(t1->UNKNOWN.mustendemp, t1->UNKNOWN.mustconn, t2, vl))
- becomes(t1, t2);
- }
- break;
-
- case kindSINGLEARROW:
- if (t2->kind == kindSINGLEARROW)
- return BuildSINGLEARROW(upper(t2->SINGLEARROW.tcarg, t1->SINGLEARROW.tcarg, vl),
- lower(t1->SINGLEARROW.tcres, t2->SINGLEARROW.tcres, vl));
- else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindINT:
- if (t2->kind != kindINT)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindFLOAT:
- if (t2->kind != kindFLOAT)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindBOOL:
- if (t2->kind != kindBOOL)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSTRING:
- if (t2->kind != kindSTRING)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSYSTY:
- if (t2->kind == kindSYSTY) {
- direrfnd = false;
- di = uplodir(true, t1->SYSTY.sysdirs, t2->SYSTY.sysdirs, &direrfnd,
- vl);
- ht = lower(t1->SYSTY.syscomp, t2->SYSTY.syscomp, vl);
- if (direrfnd)
- ht = BuildUNKNOWN(newname(), false, true);
- return BuildSYSTY(di, ht);
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- /*
- else
- if t2^.kind=APS
- then
- compat(t1,BuildSYSTY(BuildOd(BuildNON),BuildBUNDLE(ht)),vl)
- else if t2^.kind=BUNDLE
- then
- compat(t1,
- BuildSYSTY(BuildCd(BuildOd(BuildIN),BuildOd(BuildOUT))
- ,
- BuildBUNDLE(BuildCT(ht, t2^.typc4))
- )
- ,vl)
- */
- break;
-
- case kindAPS:
- /* if t2^.kind = SYSTY
- then begin
- compat(t2,BuildSYSTY(BuildOd(BuildNON),BuildBUNDLE(ht)),vl);
- lower:=t2
- end
- else */
- if (t2->kind != kindAPS)
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindCT:
- if (t2->kind == kindCT)
- return BuildCT(lower(t1->CT.tcfirst, t2->CT.tcfirst, vl),
- lower(t1->CT.tcrest, t2->CT.tcrest, vl));
- else if (t2->kind == kindSOME) {
- if (!occurs(t2->SOME.somnr, t1)) {
- ht = BuildCT(t2->SOME.tcpart, BuildSOME(t2->SOME.tcpart, newname()));
- becomes(t2, ht);
- return lower(t1, ht, vl);
- } else
- {error(11L, t1, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindLOC:
- if (t2->kind == kindLOC) {
- if (!(Equalsymbol(t2->LOC.locname, t1->LOC.locname) &&
- t1->LOC.inst == t2->LOC.inst))
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindBASETY:
- if (t2->kind == kindBASETY) {
- if (!(Equalsymbol(t1->BASETY.btname, t2->BASETY.btname) &&
- t1->BASETY.bnr == t2->BASETY.bnr))
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindSOME:
- if (t2->kind == kindCT) {
- if (!occurs(t1->SOME.somnr, t2)) {
- ht = BuildCT(t1->SOME.tcpart, BuildSOME(t1->SOME.tcpart, newname()));
- becomes(t1, ht);
- return lower(ht, t2, vl);
- } else
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- } else if (t2->kind == kindSOME) {
- ht = BuildSOME(lower(t1->SOME.tcpart, t2->SOME.tcpart, vl),
- t2->SOME.somnr);
- if (t1->SOME.somnr != t2->SOME.somnr) {
- if (!occurs(t1->SOME.somnr, t2)) becomes(t1, t2); /* !! moet dit wel? */
- else
- {error(11L, t2, NULL, NULL, NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- return ht;
- }
- } else if (t2->kind == kindEMPTYT) {
- if (!forfull)
- becomes(t1, t2);
- } else
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
-
- case kindEMPTYT:
- if (t2->kind == kindSOME) {
- if (!forfull)
- becomes(t2, t1);
- } else {
- if (t2->kind != kindEMPTYT) /* and (t2^.kind<>LIST) */
- {error(12L, t2, t1, NULL, vl, false);
- return BuildUNKNOWN(newname(),false,false);}
- }
- /* else if t2^.kind=BUNDLE
- then lower:=lower(t1,t2^.typc4,vl) */
- break;
-
- case kindALL:
- /* ALL needs not be treated here */
- {error(10L, NULL, NULL, Buildsymbol( "lower", 5L), NULL, false);
- return BuildUNKNOWN(newname(),false,false);}
- break;
- }
- return t1;
- } /* lower */
-